﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using AutoMapper;
using Cnm.Core;
using Cnm.Core.Caching;
using Cnm.Core.Ultities;
using Cnm.Models;
using Cnm.Models.ViewModels;
using Cnm.Mvc.Web.Infrastructure;
using Cnm.Mvc.Web.Ultilities;
using Cnm.Servicers.Cacher;
using Cnm.Servicers.Localization;
using Cnm.Servicers.Seo;
using PagedList;

namespace Cnm.Mvc.Web.Controllers
{
    public class PostController : Controller
    {
        private readonly CnmDemoEntities dbContext = new CnmDemoEntities();
        private readonly IUrlRecordService _urlRecordService;
        private ICacher _cacher;
        private IWorkContext _workContext;
        private readonly ICacheManager _cacheManager;
        private const int WidthThumb = 150;
        private const int WidthNormal = 750;
        /// <summary>
        /// Key for ProductBreadcrumbModel caching
        /// </summary>
        /// <remarks>
        /// {0} : product id
        /// {1} : language id
        /// </remarks>
        public const string PRODUCT_BREADCRUMB_MODEL_KEY = "Nop.pres.product.breadcrumb-{0}-{1}";
        public const string PRODUCT_BREADCRUMB_PATTERN_KEY = "Nop.pres.product.breadcrumb";

        public PostController(IUrlRecordService urlRecordService, ICacher caher, IWorkContext workContext, ICacheManager cacheManager)
        {
            _urlRecordService = urlRecordService;
            _cacher = caher;
            _workContext = workContext;
            _cacheManager = cacheManager;
        }

        public ActionResult Index()
        {
            return View();
        }

        public ActionResult Create()
        {
            return View();
        }

        [HttpPost]
        public ActionResult Create(PostModel model, string[] fileNames)
        {
            if (ModelState.IsValid)
            {

                #region Create Post

                var post = Mapper.Map(model, new Post());
                post.DateCreated = DateTime.Now;

                dbContext.Posts.Add(post);
                dbContext.SaveChanges();

                _urlRecordService.ValidateAndSaveSlug(post, model.SeName, model.Name, 0);

                #endregion

                #region Create Image

                if (fileNames != null)
                {
                    foreach (var fileName in fileNames)
                    {
                        var files = fileName.Split(new char[] {','}, StringSplitOptions.RemoveEmptyEntries);
                        foreach (var file in files)
                        {
                            //if (System.IO.File.Exists(Path.Combine(Server.MapPath(PostImagePath), fileName)))
                            {
                                var img = new Image
                                {
                                    DateCreated = DateTime.Now,
                                    FileName = file,
                                    //FullPath = Path.Combine(Server.MapPath(PostImagePath), fileName),
                                    SeoFileName = file
                                };
                                dbContext.Images.Add(img);
                                dbContext.SaveChanges();

                                var postImage = new Post_Image
                                {
                                    ImageId = img.Id,
                                    PostId = post.Id,
                                    DisplayOrder = 0
                                };
                                dbContext.Post_Image.Add(postImage);
                                dbContext.SaveChanges();
                            }
                        }
                    }
                }


                #endregion

                ViewBag.Completed = true;
                ViewBag.SeName = post.GetSeName();
                return View();
            }
            else
            {
                return View(model);
            }
        }

        public ActionResult PostDetails(int postId)
        {
            var post = dbContext.Posts.FirstOrDefault(p => p.Id == postId);
            var postDetailsViewMode = new PostDetailsViewModel
            {
                Id = post.Id,
                Name = post.Name,
                SeName = post.GetSeName(),
                Category = post.Category != null 
                ?new CategoryViewModel
                {
                    Id = post.Category.Id,
                    Name = post.Category.Name,
                    SeName = post.Category.GetSeName(),
                    UrlDetails = Url.RouteUrl("Category", new {SeName = post.Category.GetSeName()})
                }
                : new CategoryViewModel(),
                Price = post.Price,
                Region = post.Region!= null
                ? new RegionViewModel
                {
                    Name = post.Region.Name,
                    SeName = post.Region.GetSeName(),
                    UrlDetails = Url.RouteUrl("Region", new {SeName = post.Region.GetSeName()})
                }
                : new RegionViewModel(),
                DateCreated = post.DateCreated,
                FullDescription = post.FullDescription,
                ItemStatus = post.ItemStatu != null ? post.ItemStatu.Name : string.Empty,
                PaymentMethod = post.PaymentMethod != null ? post.PaymentMethod.Name : string.Empty,
                PictureViewModels = post.Post_Image != null
                    ? post.Post_Image.Select(p => new PictureViewModel
                    {
                        PictureId = p.ImageId,
                        DisplayOrder = p.DisplayOrder,
                        PictureName = p.Image.FileName,
                    }).ToList()
                    : new List<PictureViewModel>(),
                PostType = post.PostType != null ? post.PostType.Name : string.Empty,
                Poster = new PosterDetailsViewModel
                {
                    Name = post.PosterName,
                    Address = post.PosterAddress,
                    Email = post.PosterEmail,
                    Phone = post.PosterPhone
                },
                ShippingProcess = post.ShippingProcess,
                Titular = post.Titular != null ? post.Titular.Name : string.Empty,
                DateUpdated = post.DateUpdated
            };

            #region Breadcrumb

            //do not prepare this model for the associated products. any it's not used
            var breadcrumbCacheKey = string.Format(PRODUCT_BREADCRUMB_MODEL_KEY, post.Id, _workContext.WorkingLanguage.Id);
            postDetailsViewMode.Breadcrumb = _cacheManager.Get(breadcrumbCacheKey, () =>
            {
                var breadcrumbModel = new PostBreadcrumbModel()
                {
                    Enabled = true,
                    PostId = post.Id,
                    PostName = post.GetLocalized(x => x.Name),
                    PostSeName = post.GetSeName()
                };
                var productCategories = post.Category;
                if (productCategories != null)
                {
                    var catBrs = new CategoryExtensions().GetCategoryBreadCrumb(post.Category);

                    foreach (var catBr in catBrs)
                    {
                        breadcrumbModel.CategoryBreadcrumb.Add(new CategoryViewModel()
                        {
                            Id = catBr.Id,
                            Name = catBr.GetLocalized(x => x.Name),
                            SeName = catBr.GetSeName()
                        });
                    }
                }
                return breadcrumbModel;
            });

            #endregion

            return View(postDetailsViewMode);
        }

        #region Image

        public ActionResult Save(IEnumerable<HttpPostedFileBase> files)
        {
            var pictureViewModel = new PictureViewModel();
            // The Name of the Upload component is "files"
            if (files != null)
            {
                foreach (var file in files)
                {
                    if (file.ContentLength > 0)
                    {
                        var oldName = file.FileName;
                        string fileName = ImageHelper.RenameImageUploadFile(
                            file,
                            WebManager.PostImageFolderPath,
                            WidthNormal,
                            WidthThumb);
                    // Normal Image
                    var physicalPath = Path.Combine(Server.MapPath(WebManager.PostImageNormalFolderPath), fileName);
                    // The files are not actually saved in this demo
                    file.SaveAs(physicalPath);


                    string pictureUrl = (WebManager.PostImageThumbFolderPath) + fileName;
                    pictureViewModel.PictureId = 1;
                    pictureViewModel.PictureName = oldName;
                        pictureViewModel.PictureNewName = Path.GetFileName(fileName);
                    pictureViewModel.PictureUrl = pictureUrl;
                    pictureViewModel.Status = true;
                }
            }
            }

            // Return an empty string to signify success
            return Json(pictureViewModel, JsonRequestBehavior.AllowGet);
        }

        public ActionResult Remove(string[] fileNames)
        {
            // The parameter of the Remove action must be called "fileNames"

            if (fileNames != null)
            {
                foreach (var fullName in fileNames)
                {
                    var fileName = Path.GetFileName(fullName);
                    ImageHelper.DeleteImageUploadByName(fileName, WebManager.PostImageFolderPath);
                    //var physicalPath = Path.Combine(Server.MapPath(PostImagePath), fileName);

                    //// TODO: Verify user permissions

                    //if (System.IO.File.Exists(physicalPath))
                    //{
                    //    // The files are not actually removed in this demo
                    //     System.IO.File.Delete(physicalPath);
                    //}
                }
            }

            // Return an empty string to signify success
            return Content("");
        }

        #endregion
    }
}